/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[欢迎加盟知启蒙，一起邂逅框架梦]
 * 
 * https://www.zhiqim.com/gitcan/zhiqim/zhiqim_account.htm
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.zhiqim.account.api.connect;

import java.sql.SQLException;

import org.zhiqim.account.ZacConstants;
import org.zhiqim.kernel.httpclient.HttpGet;
import org.zhiqim.kernel.httpclient.HttpResult;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Urls;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.manager.dao.ZmrParamDao;
import org.zhiqim.orm.ORMException;

/**
 * QQ互联
 * http://wiki.connect.qq.com/
 *
 * @version v1.0.0 @author yangpeng 2018-1-26 新建与整理
 */
public class QQService implements ZacConstants
{
    /**
     * 授权，获取访问令牌
     * http://wiki.open.qq.com/wiki/website/%E4%BD%BF%E7%94%A8Authorization_Code%E8%8E%B7%E5%8F%96Access_Token
     * 
     * @param code          QQ互联回调时传入的编码
     * @return              通过编码进行授权得到结果
     * @throws SQLException 数据库异常
     * @throws ORMException 数据库异常
     */
    public static HttpResult getAccessToken(String code) throws ORMException, SQLException
    {
        String appId = ZmrParamDao.getString(ZAC_NAME, QQ_APP_ID);
        String appSecret = ZmrParamDao.getString(ZAC_NAME, QQ_APP_SECRET);
        String callback = ZmrParamDao.getString(ZAC_NAME, QQ_CALLBACK);
        
        //诊断配置
        Asserts.assertNotEmptyBlank(appId, QQ_CONF_ERR);
        Asserts.assertNotEmptyBlank(appSecret, QQ_CONF_ERR);
        Asserts.assertNotEmptyBlank(callback, QQ_CONF_ERR);
        
        //组装URL进调用
        String url = Strings.formatMessage(QQ_URL_TOKEN, appId, appSecret, Urls.encodeUTF8(callback), code);
        HttpGet conn = new HttpGet(url);
        conn.setConnectTimeout(10);
        conn.setReadTimeout(30);
        conn.setConnectionClose();
        conn.execute();
        
        if (conn.isResponseSuccess())
        {//调用不成功
            return conn.getResult();
        }
        
        //成功判断错误码
        String responseText = conn.getResponseText();
        String error = Urls.get(responseText, "code");
        if(Validates.isNotEmpty(error))
            return new HttpResult(Ints.toInt(error), Urls.get(responseText, "msg"));
        else
            return conn.getResult();
    }
    
    /**
     * 获取用户OpenID
     * http://wiki.open.qq.com/wiki/website/%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7OpenID_OAuth2.0
     * 
     * @param accessToken   访问令牌
     * @return              通过令牌获取用户编号
     */
    public static HttpResult getOpenId(String accessToken)
    {
        String url = Strings.formatMessage(QQ_URL_ME, accessToken);
        HttpGet conn = new HttpGet(url);
        conn.setConnectTimeout(10);
        conn.setReadTimeout(30);
        conn.setConnectionClose();
        conn.execute();
        
        if (conn.isResponseSuccess())
        {//调用不成功
            return conn.getResult();
        }
        
        //成功判断错误码
        String responseText = conn.getResponseText();
        String error = Urls.get(responseText, "code");
        if(Validates.isNotEmpty(error))
            return new HttpResult(Ints.toInt(error), Urls.get(responseText, "msg"));
        else
            return conn.getResult();
    }
    
    /**
     * 获取登录用户在QQ空间的信息
     * http://wiki.connect.qq.com/get_user_info
     * 
     * @param accessToken   访问令牌
     * @param openId        用户编号
     * @return              通过令牌&用户编号获取用户信息
     * @throws SQLException 数据库异常
     * @throws ORMException 数据库异常
     */
    public static HttpResult getUserInfo(String accessToken, String openId) throws ORMException, SQLException
    {
        String appId = ZmrParamDao.getString(ZAC_NAME, QQ_APP_ID);
        Asserts.assertNotEmptyBlank(appId, QQ_CONF_ERR);
        
        String url = Strings.formatMessage(QQ_URL_GET_USER_INFO, appId, accessToken, openId);
        HttpGet conn = new HttpGet(url);
        conn.setConnectTimeout(10);
        conn.setReadTimeout(30);
        conn.setConnectionClose();
        conn.execute();
        
        if (conn.isResponseSuccess())
        {//调用不成功
            return conn.getResult();
        }
        
        String responseText = conn.getResponseText();
        String error = Urls.get(responseText, "ret");
        if(!"0".equals(error))
            return new HttpResult(Ints.toInt(error), Urls.get(responseText, "msg"));
        else
            return conn.getResult();
    }
}
